package bma.common.netty.property;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelEvent;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.ChannelUpstreamHandler;

public class ChannelProperties {

	private static class Handler implements ChannelUpstreamHandler {

		protected ChannelProperties prop;

		public Handler(ChannelProperties prop) {
			super();
			this.prop = prop;
		}

		@Override
		public void handleUpstream(ChannelHandlerContext ctx, ChannelEvent e)
				throws Exception {
			if (e instanceof ChannelStateEvent) {
				ChannelStateEvent evt = (ChannelStateEvent) e;
				switch (evt.getState()) {
				case OPEN:
					if (!Boolean.TRUE.equals(evt.getValue())) {
						prop.channelClosed();
					}
					break;
				}
			}
			ctx.sendUpstream(e);
		}

	}

	public static ChannelProperties bind(Channel ch) {
		ChannelPipeline p = ch.getPipeline();
		Handler h = p.get(Handler.class);
		if (h == null) {
			h = new Handler(new ChannelProperties());
			p.addLast("channelProperties", h);
		}
		return h.prop;
	}

	private Map<String, Object> data = new ConcurrentHashMap<String, Object>();

	public void channelClosed() {
		data.clear();
	}

	public Object getProp(String name) {
		return data.get(name);
	}

	public <TYPE> TYPE getProp(String name, Class<TYPE> cls) {
		Object r = data.get(name);
		if (r != null)
			return cls.cast(r);
		return null;
	}

	public void setProp(String name, Object value) {
		data.put(name, value);
	}

}
